package com.sdp.th.netty.handler;

import java.math.BigDecimal;
import java.time.LocalDateTime;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.sdp.core.bizc.utils.ApplicationContextUtils;
import com.sdp.th.entity.ThEqState;
import com.sdp.th.netty.actor.ActorManager;
import com.sdp.th.netty.bizc.BusinessEnum;
import com.sdp.th.netty.channel.ChannelManager;
import com.sdp.th.netty.channel.ChannelSession;
import com.sdp.th.netty.pojo.NettyMessage;
import com.sdp.th.netty.utils.NettyUtils;
import com.sdp.th.utils.ThConstants;

import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

@Component
@Sharable
@Slf4j
public class MyHandler extends SimpleChannelInboundHandler<String> {

	@Autowired
	private ChannelManager channelManager;

	// 给客户端发消息
	// private void sendInfo(ChannelHandlerContext ctx , String info) {
	// ctx.writeAndFlush(info);
	// ctx.flush();
	// }

	/**
	 * 心跳检测和处理
	 * 
	 * @param ctx
	 * @param evt
	 * @throws Exception
	 */
	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		if (evt instanceof IdleStateEvent) {
			IdleStateEvent event = (IdleStateEvent) evt;
			// if (event.state() == IdleState.READER_IDLE) {
			// System.out.println("读空闲");
			// } else if (event.state() == IdleState.WRITER_IDLE) {
			// System.out.println("写空闲");
			// } else if (event.state() == IdleState.ALL_IDLE) {
			// System.out.println("读写空闲");
			// }

			if (event.state() == IdleState.READER_IDLE) {
				ChannelSession session = channelManager.getSession(ctx.channel().id());

				/*
				if (!StringUtils.isEmpty(session.getDeviceNo())) {
					NettyMessage nettyMessage = new NettyMessage();
					nettyMessage.setBusinessType(BusinessEnum.设备离线);
					nettyMessage.setMessageContent(session.getDeviceNo());

					ApplicationContextUtils.getBean(ActorManager.class).tell(nettyMessage, session.getDeviceNo());
				}
				*/

				log.info("服务器主动断开连接，连接的session信息为：[{}]", session);
				ctx.channel().close();

			}

		} else {
			super.userEventTriggered(ctx, evt);
		}
	}

	/**
	 * 链接建立后
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		log.info("********链接成功");
		channelManager.initChannel(ctx.channel());
		super.channelActive(ctx);
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

		log.info("***********收到报文 ：{}", msg);

		// 将消息传递给Pipeline中的下一个入站处理器
		// ctx.fireChannelRead(msg);
		// 将消息传入出站
		// ctx.writeAndFlush(msg);
		
//		if(msg.length()==NettyUtils.MESSAGE_TH_LENGTH) {
//			thMessage(ctx, msg);
//		}
		
//		if(msg.indexOf("zsp")>-1) {
//			smokeMessage(ctx, msg);
//		}else {
//			thMessage(ctx, msg);
//		}
		
		try {
			thMessage(ctx, msg);
		} catch (Exception e) {
			log.error("处理报文:{} 时出现异常",msg);
			log.error(NettyUtils.stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace()));
		}

	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		log.error("********链接异常关闭：{}", cause.getLocalizedMessage());
		log.error(cause.getMessage());
		ctx.close();
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		log.info("********离线");
		super.channelInactive(ctx);
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	/**
	 * 温湿度报文处理
	 * @param ctx
	 * @param msg
	 */
	private void thMessage(ChannelHandlerContext ctx, String msg) {
		log.info("温湿度报文："+msg);
		String deviceNo  = NettyUtils.hexToDecimal(msg.substring(62, 78));
		// 将设备与通道绑定
		if (!StringUtils.isEmpty(deviceNo)) {
			if (channelManager.isChannelExist(ctx.channel().id())) {
				channelManager.addMap(deviceNo, ctx.channel());
			} else {
				channelManager.initChannel(ctx.channel());
				channelManager.addMap(deviceNo, ctx.channel());
			}
		}

		// 湿度
		Double humidity = (Integer.parseInt(msg.substring(18, 22), 16)) / 10.0;

		// 温度
		Double temperature = (Integer.parseInt(msg.substring(22, 26), 16)) / 10.0;
		
		//电量
		String power = NettyUtils.hexToDecimal(msg.substring(58, 62));
		
		//信号
		String signal = NettyUtils.hexToDecimal(msg.substring(26, 30));

		if (humidity == null || temperature == null || StringUtils.isEmpty(deviceNo)) {
			return;
		}

		ThEqState eqState = new ThEqState();
		eqState.setDeviceNo(deviceNo);
		eqState.setOriginalMessage(msg);
		eqState.setDeviceHumidity(BigDecimal.valueOf(humidity));
		eqState.setDeviceTemperature(BigDecimal.valueOf(temperature));
		eqState.setDevicePower(new BigDecimal(power));
		eqState.setDeviceSignal(new BigDecimal(signal));
		eqState.setReportTime(LocalDateTime.now());
		eqState.setLineState(ThConstants.是.getCode());

		NettyMessage nettyMessage = new NettyMessage();
		nettyMessage.setBusinessType(BusinessEnum.报文处理业务);
		nettyMessage.setMessageContent(eqState);

		ApplicationContextUtils.getBean(ActorManager.class).tell(nettyMessage, deviceNo);
	}
}
